import { once } from '@/utils';
import React, {
  createContext,
  forwardRef,
  useContext,
  useImperativeHandle,
  useLayoutEffect,
  useRef,
  useState,
} from 'react';
import { createPortal } from 'react-dom';

const Ctx = createContext();

const copyStyleSheet = (container) => {
  const styleNodes = document.getElementsByTagName('style');
  const linkNodes = document.getElementsByTagName('link');
  for (const node of styleNodes) {
    container.appendChild(node.cloneNode(true));
  }
  for (const node of linkNodes) {
    container.appendChild(node.cloneNode(true));
  }
};

Frame = forwardRef(Frame);

function Frame(props, $ref) {
  const { children, ...rest } = props;
  const ref = useRef();
  useImperativeHandle($ref, () => ref.current);

  const [container, setContainer] = useState();

  const updateContainer = () => {
    const body = ref.current.contentWindow.document.body;
    setTimeout(() => {
      copyStyleSheet(body);
    });
    setContainer(body);
  };

  useLayoutEffect(() => {
    if (ref.current?.contentWindow?.document?.body) {
      updateContainer();
    } else {
      once(ref.current, 'load', updateContainer);
    }
  }, []);

  return (
    <>
      <iframe ref={ref} {...rest} />
      {container && <Ctx.Provider value={ref.current.contentWindow} children={createPortal(children, container)} />}
    </>
  );
}

export function useFrameWindow() {
  return useContext(Ctx);
}

export default Frame;
